import { ILoginModel, LoginStatus, OptionsCallback } from '@/models/login'
import { Status } from '@/models/sys'
import * as API from '@/service/index/login'
import { useUserStore } from '@/store'
import { awaitTo } from '@/utils'

interface IState {
  code: string
  appId: string
  qrcode: string
  checkLoginData: ILoginModel
}

const createCheckData = () => {
  const checkLoginData: ILoginModel = {
    uuid: '',
    need_qrcode: Status.Yes,
    qrcode_status: Status.Yes,
    need_code: Status.Yes,
    code_status: Status.Yes,
    need_secondary_qrcode: Status.Yes,
    secondary_qrcode_status: Status.Yes,
    status: LoginStatus.Unlogged,
    error: '',
  }

  return checkLoginData
}

const useLogin = (options?: OptionsCallback) => {
  const state = reactive<IState>({
    code: '',
    appId: '',
    qrcode: '',
    checkLoginData: createCheckData(),
  })

  async function getCode() {
    return new Promise((resolve) => {
      wx.qy.login({
        success: function (res) {
          if (res.code) {
            state.code = res.code

            resolve(true)
          } else {
            uni.showToast({
              title: '获取code失败',
              icon: 'none',
            })
          }
        },
        fail: function (res) {
          uni.showToast({
            title: '获取code失败',
            icon: 'none',
          })
        },
      })
    })
  }

  const { userInfo, setToken, getAppId } = useUserStore()

  /** 临时授权登录 */
  async function getLogin() {
    await getCode()
    const { result, err } = await awaitTo(
      API.login({
        app_id: getAppId(),
        code: state.code,
      }),
    )

    if (result) {
      uni.hideLoading()
      setToken(result.data.token)
    }
  }

  /** 获取 iPad 登录的二维码 */
  async function getIpadLoginQrCode(callback?: () => void) {
    uni.showLoading({ title: '请稍等' })
    await getLogin()
    if (!userInfo.token) return

    uni.showLoading({ title: '请稍等' })
    const { result } = await awaitTo(API.getIpadLoginQrCode())

    if (result?.data) {
      uni.hideLoading()

      state.qrcode = result.data.qrcode
      callback && callback()

      openTimer()
    }
  }

  const timer = ref()

  /** 定时器 */
  function openTimer() {
    closeTimer()
    timer.value = setInterval(() => {
      checkLoginResult()
    }, 1200)
  }

  /** 关闭定时器 */
  function closeTimer() {
    clearInterval(timer.value)
    timer.value = null
  }

  /** 检查登录结果 */
  async function checkLoginResult() {
    if (!useUserStore().userInfo.token) return

    const { result, err } = await awaitTo(API.checkLoginResult())
    if (result?.data) {
      console.log('登录结果', result.data)

      const resData = result.data

      state.checkLoginData = resData

      /** 是否需要扫码 */
      const isQrCode = resData.need_qrcode === Status.Yes
      /** 登录成功 */
      const isSuccessStatus = resData.status === LoginStatus.Success
      /** 是否需要再次扫描二维码验证 */
      const isNeedSecondaryQrcode = resData.need_secondary_qrcode === Status.Yes
      /** 二维码扫描结果 */
      const isQrcodeFail = resData.qrcode_status === Status.No
      /** 是否需要验证码 */
      const isNeedCode = resData.need_code === Status.Yes
      /** 二次验证码验证结果 */
      const SecondaryQrcodeStatus = resData.secondary_qrcode_status === Status.No

      if (resData.qrcode_status === Status.Yes && isQrCode && !isNeedCode) {
        uni.showLoading({ title: '登录中', mask: true })
      }

      if (resData.secondary_qrcode_status === Status.Yes && isNeedSecondaryQrcode) {
        uni.showLoading({ title: '登录中', mask: true })
      }

      if (isQrCode) {
        options.needQrcode()
      } else if (isQrcodeFail) {
        options.scanQrcode(Status.No)
        uni.showModal({
          title: '扫描二维码失败',
          content: '重新刷新二维码',
          showCancel: false,
          confirmText: '刷新',
          success: function (res) {
            if (res.confirm) {
              getIpadLoginQrCode()
            }
          },
        })
      }
      if (isSuccessStatus) {
        uni.hideLoading()
        options.successLogin()
      }
      if (isNeedSecondaryQrcode) {
        getSecondQrCode()
        options.needSecondaryQrcode()
      }

      if (SecondaryQrcodeStatus && resData.secondary_qrcode_status === Status.Yes) {
        uni.showToast({ title: '验证失败', icon: 'none' })
      }
      if (isNeedCode) {
        options.needCode()
      }
    }

    if (err) {
      closeTimer()
      uni.hideLoading()
    }
  }

  /** 二次扫描二维码 */
  async function getSecondQrCode() {
    const { result } = await awaitTo(API.getSecondQrCode())
    if (result?.data) {
      state.qrcode = result.data.qrcode
    }
  }

  /** 二次验证登录 */
  async function verifyCode(
    prams: { code: string },
    callback: () => void,
    errCallback: () => void,
  ) {
    const { result, err } = await awaitTo(API.verifyCode(prams))
    if (result) {
      callback()
    }
    if (err) {
      errCallback()
    }
  }

  /** 退出登录 */
  const logout = async (onFinish: () => void) => {
    const { err, result } = await awaitTo(API.logout())
    uni.hideLoading()
    if (result) {
      onFinish()
    }
  }

  return {
    ...toRefs(state),
    getLogin,
    getIpadLoginQrCode,
    getCode,
    checkLoginResult,
    closeTimer,
    openTimer,
    verifyCode,
    logout,
  }
}

export default useLogin
